package com.it.mmx.memory.circuit.breaker.autoconfigure;

import com.it.mmx.memory.circuit.breaker.config.MemoryCircuitBreakerProperties;
import com.it.mmx.memory.circuit.breaker.interceptor.MemoryCircuitBreakerInterceptor;
import com.it.mmx.memory.circuit.breaker.monitor.SystemMemoryMonitor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 内存熔断自动配置类
 * 仅当 memory.circuitbreaker.enabled=true 时生效
 * @author 刘仲
 */
@Configuration
@EnableConfigurationProperties( MemoryCircuitBreakerProperties.class)
@ConditionalOnProperty(prefix = "memory.circuitbreaker", name = "enabled", havingValue = "true")
public class MemoryCircuitBreakerAutoConfiguration {

    /**
     * 注册内存监控器
     */
    @Bean
    public SystemMemoryMonitor systemMemoryMonitor( MemoryCircuitBreakerProperties properties) {
        return new SystemMemoryMonitor(properties.getThresholdPercent());
    }

    /**
     * 注册熔断拦截器
     */
    @Bean
    public MemoryCircuitBreakerInterceptor memoryCircuitBreakerInterceptor(
            SystemMemoryMonitor memoryMonitor,
            MemoryCircuitBreakerProperties properties) {
        return new MemoryCircuitBreakerInterceptor(memoryMonitor, properties);
    }

    /**
     * 配置拦截器（仅在Spring MVC环境下生效）
     */
    @Configuration
    @ConditionalOnClass(DispatcherServlet.class)
    public static class WebMvcInterceptorConfig implements WebMvcConfigurer {

        private final MemoryCircuitBreakerInterceptor interceptor;

        public WebMvcInterceptorConfig(MemoryCircuitBreakerInterceptor interceptor) {
            this.interceptor = interceptor;
        }

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 拦截所有请求，内部根据配置的路径进行匹配
            registry.addInterceptor(interceptor)
                    .addPathPatterns("/**")
                    .order(0); // 最高优先级，确保在业务拦截器前执行
        }
    }
}
